


#ifndef SUBJECT_H
#define SUBJECT_H



#include <stdint.h>
#include "color.h"
#include "expression.h"



/// Interface that must be supported by all mutable objects
class IMutable
{
    virtual bool isLikeInitial() const =0; //< tells if important features are like initial
    virtual bool mutate() =0;  //< mutates and returns true if returned to initial normal state
    virtual void restore() =0; //< restores the state to initial    
};



class Subject : public IMutable
{
public:
    Subject( bool truth, Color::eColor col );
    
    Color getColor() const { return m_Color; }
    bool tellsTruth() const { return m_bPendingTruth; }
    virtual bool isLikeInitial() const =0; //< tells if important features are like initial
    virtual bool mutate();  //< mutates and returns true if returned to initial normal state
    virtual void restore(); //< restores the state to initial
    
    void addExpression( Expression *exp ); //< add expression to the m_Expressions collection
    void mutateExpressions( CollectionExpressions *exprs ){ m_pPendingExpressions = exprs; }
    CollectionExpressions &getExpressions() { return *m_pPendingExpressions; }

    /// output to a stream 
    virtual void putText( std::ostream &S ) const =0;
    
protected:
    Color m_Color;
    
    bool m_bTruth;
    bool m_bPendingTruth;    

    CollectionExpressions m_Expressions;
    CollectionExpressions *m_pPendingExpressions;    
};



typedef Collection <Subject> CollectionSubjects;



std::ostream & operator << ( std::ostream &S, const Subject &subj );



#endif
